﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.NetworkInformation;
using System.Text;

namespace Common.Encrypt
{
    /// <summary>
    /// 提供对字符串进行硬加密功能
    /// </summary>
    public static class HardwareProvider
    {
        /// <summary>
        /// 默认秘钥
        /// </summary>
        private static string Key = "3C02A379965AB0DFCD77B1C484450433";

        /// <summary>
        /// 当前版本
        /// </summary>
        public static string Version = "1.0.0.0";

        /// <summary>
        /// 解码
        /// </summary>
        /// <param name="str">密文</param>
        /// <returns>返回一个密文被解码后的明文</returns>
        public static string Decode(string str)
        {
            string key = GetHardwareKey();
            string value = str.Substring(Version.Length);
            value = AESProvider.Decode(value, key);
            value = value.Substring(32);
            return value;
        }


        /// <summary>
        /// 编码
        /// </summary>
        /// <param name="str">内容</param>
        /// <returns>返回一个明文被编码后的密文</returns>
        public static string Encode(string str)
        {
            string key = GetHardwareKey();
            string value = Guid.NewGuid().ToString("N") + str;
            value = AESProvider.Encode(value, key);
            return Version + value;
        }

        private static string GetHardwareKey()
        {
            string str = string.Concat(Key, Computer.Instance.CPU_ID, Key, Computer.Instance.MAC_Address);
            return MD5Provider.Encode(str);
        }

        /// <summary>
        /// 计算机信息
        /// </summary>
        private class Computer
        {
            public static readonly Computer Instance = new Computer();

            private string _cpu_Id;
            private string _mac_Address;
            public string CPU_ID
            {
                get
                {
                    if (_cpu_Id == string.Empty)
                    {
                        _cpu_Id = GetCPUID();
                    }
                    return _cpu_Id;
                }
            }

            public string MAC_Address
            {
                get
                {
                    if (_mac_Address == string.Empty)
                    {
                        _mac_Address = GetMacAddress();
                    }
                    return _mac_Address;
                }
            }

            private string GetCPUID()
            {
                try
                {
                    //获取CPU序列号代码 
                    string cpuInfo = "";//cpu序列号 
#if netstandard2_0
                    if (System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Linux))
                    {
                        cpuInfo = ReadCpuSerialNumberFromLinux();
                    }
#endif
#if net46
                    ManagementClass mc = new ManagementClass("Win32_Processor");
                    ManagementObjectCollection moc = mc.GetInstances();
                    foreach (ManagementObject mo in moc)
                    {
                        cpuInfo = mo.Properties["ProcessorId"].Value.ToString();
                    }
                    moc = null;
                    mc = null;
#endif
                    return cpuInfo;
                }
                catch (Exception ex)
                {
                    throw new Exception("获取计算机的CPU ID出现异常", ex);
                }
                finally
                {
                }

            }
            /// <summary>
            /// 读取CPU序列号信息（linux）
            /// </summary>
            /// <returns></returns>
            private static string ReadCpuSerialNumberFromLinux()
            {
                const string CPU_FILE_PATH = "/proc/cpuinfo";
                var s = File.ReadAllText(CPU_FILE_PATH);
                var lines = s.Split(new[] { '\n' });
                s = string.Empty;

                foreach (var item in lines)
                {
                    if (item.StartsWith("Serial"))
                    {
                        var temp = item.Split(new[] { ':' });
                        s = temp[1].Trim();
                        break;
                    }
                }
                return s;
            }
            private string GetMacAddress()
            {
                try
                {
                    //获取网卡硬件地址 
                    string mac = "";

                    NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
                    if (nics == null || nics.Length <= 0)
                    {
                        return mac;
                    }
                    List<string> macList = new List<string>();
                    foreach (var ni in nics.Where(it => it.NetworkInterfaceType != NetworkInterfaceType.Loopback && it.OperationalStatus == OperationalStatus.Up))
                    {
                        IPInterfaceProperties ip = ni.GetIPProperties();
                        var unicastAddr = ip.UnicastAddresses;
                        if (unicastAddr.Any(t => t.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork))
                        {
                            var addr = ni.GetPhysicalAddress();
                            macList.Add(addr.ToString());
                        }
                    }
                    return macList.Count > 0 ? macList[0] : "";

                }
                catch (Exception ex)
                {
                    throw new Exception("获取计算机的MAC地址出现异常", ex);
                }
                finally
                {
                }

            }

        }
    }
}
